const jwt = require('jsonwebtoken')
const errorType = require('../constants/error-type')
const userService = require('../service/user.service')
const authService = require('../service/auth.service')
const md5password = require('../utils/passwoed-hanle')
const {
  PUBLIC_KEY
} = require('../app/config')
const verifyLogin = async (ctx, next) => {
  //1.获取用户名和密码
  const {
    name,
    password
  } = ctx.request.body

  // 2.判断用户名和密码是否为空
  if (!name || !password) {
    const error = new Error(errorType.NAME_OR_PASSWORD_IS_REQUIRED)
    return ctx.app.emit('error', error, ctx)
  }
  // 3.判断用户是否存在
  const result = await userService.getUserByName(name)
  const user = result[0]
  if (!user) {
    const error = new Error(errorType.USER_DOES_NO_EXISTS)
    return ctx.app.emit('error', error, ctx)
  }
  // 4.判断用户名密码是否和数据库中的密码是否一致(加密)
  if (md5password(password) !== user.password) {
    const error = new Error(errorType.PASSWORD_IS_ERROR)
    return ctx.app.emit('error', error, ctx)
  }
  ctx.user = user
  await next()
}
const verifyAuth = async (ctx, next) => {
  console.log('验证登录的middleware')
  //获取token
  const authorization = ctx.headers.authorization
  if (!authorization) {
    const error = new Error(errorType.INVALID_TOKEN)
    ctx.app.emit('error', error, ctx)
    return
  }
  const token = authorization.replace('Bearer ', '')
  // 验证token
  try {
    const result = jwt.verify(token, PUBLIC_KEY, {
      algorithms: ['RS256']
    })
    ctx.user = result
    await next()
  } catch (err) {
    const error = new Error(errorType.INVALID_TOKEN)
    ctx.app.emit('error', error, ctx)
    return
  }
}
const verifyPermission = (tableName) => {
  return async (ctx,next) => {
    console.log('验证是否有权限的middleware')
    //获取参数
    const {id} = ctx.user
    const paramsId = ctx.params[`${tableName}Id`]
    //查询
    try {
      const isPermission = await authService.checkResource(paramsId, id,tableName)
      if(!isPermission) throw new Error()
      await next()
    } catch (err) {
      const error = new Error(errorType.UNAUTHORIZATION)
      ctx.app.emit('error', error, ctx)
    }
  }
}
module.exports = {
  verifyLogin,
  verifyAuth,
  verifyPermission
}